<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;

use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Config;
use App\Models\SmsTpl;
use App\Models\Record\Send\Sms;
use Crypt;
use Log;

class ResetPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Where to redirect users after resetting their password.
     *
     * @var string
     */
    protected $redirectTo = '/';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * 手机注册验证
     * @param  array  $data [description]
     * @return [type]       [description]
     */
    private function checkPhoneValidator(array $data)
    {
        $attribute =  array(
            'phone' => '手机号',
            'captcha' =>  '验证码',
        );

        $message  = array(
            'required' => ':attribute必须填写',
            'regex' => '手机号格式错误',
            'captcha' => '图片验证码错误',
        );
        return Validator::make($data, [
            'phone' => ['regex:/^(139|138|137|136|135|134|147|150|151|152|157|158|159|178|182|183|184|187|188|130|131|132|155|156|185|186|145|176|133|153|177|173|180|181|189|170|171)\d{8}$/'],
            'captcha' => 'bail|required|captcha',
        ],$message,$attribute);
    }

    /**
     * 密码验证
     * @param  array  $data [description]
     * @return [type]       [description]
     */
    private function checkPwdValidator(array $data){
        $attribute =  array(
            'password' => '密码',
            'captcha' =>  '验证码',
        );

        $message  = array(
            'required' => ':attribute必须填写',
            'confirmed' => ':attribute不相同',
            'min' => '最小:min字符',
            'max' => '最大:max字符',
        );
        return Validator::make($data, [
           'password' => 'required|confirmed|min:6|max:15',
        ],$message,$attribute);
    }

    /**
     * 找回密码验证手机号
     * @return [type] [description]
     */
    public function phoneCheck(Request $request){
        $validator = $this->checkPhoneValidator($request->all());
        if($validator->fails()){
            $this->ajaxJson(10,$validator->errors()->first());
        }
        $phone = $request->input('phone');
        $this->checkPhoneNonExists($phone);
        $this->ajaxJson(0,'',['phonekey'=>Crypt::encrypt($phone)]);
    }

    /**
     * 找回密码发送验证码
     * @return [type] [description]
     */
    public function sendCode(Request $request){
        $phone = $request->input('phone');
        $this->checkPhoneNonExists($phone);
        
        $config = new Config();
        //获取短信服务商
        $smsConfig = $config->cacheFindByKey('sms');
        if(!$smsConfig || $smsConfig->vue==''){
            Log::error("找回账号失败,未获取到全局sms配置");
            $this->ajaxJson(10,'发送失败,请稍后重试');
        }
        $smsService = Config::where(['key'=>'sms_service','vue'=>$smsConfig->vue])->first();
        if(!$smsService){
            Log::error("找回账号失败,未获取到sms_service短信服务商配置");
            $this->ajaxJson(10,'发送失败,请稍后重试');
        }
        //获取短信服务商绑定手机号模版
        $smsTpl = SmsTpl::where(['config_id'=>$smsService->id,'module'=>'findPwd'])->first();
        if(!$smsTpl){
            Log::error("找回账号失败,未获取到短信服务商找回短信模版");
            $this->ajaxJson(10,'发送失败,请稍后重试');
        }
        //发送短信
        $smstpl_id = $smsTpl->sendSms($phone,$smsConfig->vue,['code'=>substr(mt_rand(), 0,6)],$request->getClientIp());
        if(!$smstpl_id || $smsTpl['returnMsg']['code']==1){
            $this->ajaxJson(10,$smsTpl['returnMsg']['msg']);
        }
        $this->ajaxJson(0,'发送成功',['key'=>Crypt::encrypt($smstpl_id)]);
    }

    /**
     * 找回密码验证手机验证码
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function checkCode(Request $request){
        $phone = $request->input('phone');
        $this->checkPhoneNonExists($phone);
        $this->checkPhoneKey($request);
        $this->checkPhoneCode($phone,$request->input('code'));
        $this->ajaxJson(0,'');
    }

    /**
     * 密码重置
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function phonePassword(Request $request){
        $validator = $this->checkPwdValidator($request->all());
        if($validator->fails()){
            $this->ajaxJson(10,$validator->errors()->first());
        }
        $phone = $request->input('phone');
        $this->checkPhoneNonExists($phone);
        $this->checkPhoneKey($request);
        $smsrecord = $this->checkPhoneCode($phone,$request->input('code'));
        $this->reset(['phone'=>$phone],bcrypt($request->input('password')));
        $smsrecord->isCheck = 1;
        $smsrecord->checkTime = date('Y-m-d H:i:s');
        $smsrecord->save();
        $this->ajaxJson(0,'密码重置成功');
    }

     /**
     * 验证手机验证码
     * @param  [type] $phone [description]
     * @return [type]        [description]
     */
    private function checkPhoneCode($phone,$code){
        $smsrecord = Sms::where(['phone'=>$phone])->orderBy('created_at','desc')->first();
        //验证发送记录、是当前手机号发送、短信过期时间、短信验证码匹配 
        if(!$smsrecord || $smsrecord->phone!=$phone || json_decode($smsrecord->params,true)['code']!=$code ){
            $this->ajaxJson(10,'短信验证码错误');
        }
        if(time()-strtotime($smsrecord->created_at)>$smsrecord->expireTime){
            $this->ajaxJson(10,'短信验证码过期,请重新获取');   
        }
        if($smsrecord->isCheck){
            $this->ajaxJson(10,'短信已失效,请重新获取');   
        }
        return $smsrecord;
    }

    /**
     * 验证手机、秘钥有效性
     * @return [type] [description]
     */
    private function checkPhoneKey($request){
        $phonekey = Crypt::decrypt($request->input('phonekey'));
        $phone = $request->input('phone');
        if($phonekey=='' || $phonekey!=$phone){
            $this->ajaxJson(10,'请求错误,请刷新页面重试');
        }
    }

    /**
     * 验证手机号不存在
     * @param  [type] $phone [description]
     * @return [type]        [description]
     */
    private function checkPhoneNonExists($phone){
        $user = User::where(['phone'=>$phone])->first();
        if(!$user){
            $this->ajaxJson(10,'手机号未注册');
        }
    }

    /**
     * 密码重置
     * @return [type] [description]
     */
    private function reset($data,$pwd){
        User::where($data)->update(['password'=>$pwd]);
    }
}
